home *** CD-ROM | disk | FTP | other *** search
/ The World's Largest Collection of Windows Software / The World's Largest Collection of Windows Software - Disc 2.iso / textproc / _b1 / fontlist / fontlist.c < prev    next >
C/C++ Source or Header  |  1989-01-22  |  12KB  |  424 lines

  1. /*    FONTLIST.C - Font Enumeration Program    */
  2.  
  3. #include    <windows.h>
  4. #include    <string.h>
  5. #include    <stdio.h>
  6. #include    "winundoc.h"
  7. #include    "fontlist.h"
  8.  
  9. typedef struct {
  10.     GLOBALHANDLE hGMem;
  11.     short nCount;
  12.     } ENUMER;
  13.  
  14. typedef struct {
  15.     short nFontType;
  16.     LOGFONT lf;
  17.     TEXTMETRIC tm;
  18.     } FONT;
  19.  
  20. long FAR PASCAL WndProc (HWND, unsigned, WORD, LONG);
  21. int FAR PASCAL EnumAllFaces (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *);
  22. int FAR PASCAL EnumAllFonts (LPLOGFONT, LPTEXTMETRIC, short, ENUMER FAR *);
  23.  
  24. char szAppName [] = "FontList";
  25.  
  26. int PASCAL WinMain(hInstance, hPrevInstance, lpszCmdLine, nCmdShow)
  27. HANDLE hInstance, hPrevInstance;
  28. LPSTR lpszCmdLine;                 /* command line             */
  29. int nCmdShow;                     /* show-window type (open/icon) */
  30. {
  31.     HWND hWnd;                     /* window handle             */
  32.     MSG msg;                     /* message                 */
  33.     WNDCLASS wndclass;
  34.     
  35.     if (!hPrevInstance) {
  36.         wndclass.style = CS_HREDRAW | CS_VREDRAW;
  37.         wndclass.lpfnWndProc = WndProc;
  38.         wndclass.cbClsExtra = 0;
  39.         wndclass.cbWndExtra = 0;
  40.         wndclass.hInstance = hInstance;
  41.         wndclass.hIcon = LoadIcon (NULL, IDI_APPLICATION);
  42.         wndclass.hCursor = LoadCursor (NULL, IDC_ARROW);
  43.         wndclass.hbrBackground = GetStockObject (WHITE_BRUSH);
  44.         wndclass.lpszMenuName = szAppName;
  45.         wndclass.lpszClassName = szAppName;
  46.         
  47.         if (!RegisterClass (&wndclass)) return FALSE;
  48.     }
  49.     
  50.     hWnd = CreateWindow (szAppName, "Font Enumeration",
  51.                     WS_OVERLAPPEDWINDOW | WS_VSCROLL,
  52.                     CW_USEDEFAULT, 0,
  53.                     CW_USEDEFAULT,    0,
  54.                     NULL, NULL, hInstance, NULL);
  55.     
  56.     ShowWindow (hWnd, nCmdShow);              /* Shows the window         */
  57.     UpdateWindow (hWnd);                  /* Sends WM_PAINT message  */
  58.     
  59.     while (GetMessage (&msg, NULL, 0, 0)) {
  60.         TranslateMessage (&msg);       /* Translates virtual key codes         */
  61.         DispatchMessage (&msg);       /* Dispatches message to window         */
  62.         }
  63.     return msg.wParam;       /* Returns the value from PostQuitMessage */
  64.     }
  65.  
  66. int FAR PASCAL EnumAllFaces (lf, tm, nFontType, enumer)
  67. LPLOGFONT lf;
  68. LPTEXTMETRIC tm;
  69. short nFontType;
  70. ENUMER FAR * enumer;
  71. {
  72.     LPSTR lpFaces;
  73.     if (NULL == GlobalReAlloc (enumer->hGMem,
  74.                         (DWORD) LF_FACESIZE * (1 + enumer->nCount),
  75.                         GMEM_MOVEABLE))
  76.         return 0;
  77.     
  78.     lpFaces = GlobalLock (enumer->hGMem);
  79.     lstrcpy (lpFaces + enumer->nCount * LF_FACESIZE, lf->lfFaceName);
  80.     GlobalUnlock (enumer->hGMem);
  81.     enumer->nCount ++;
  82.     return 1;
  83.     }
  84.  
  85. int FAR PASCAL EnumAllFonts (lf, tm, nFontType, enumer)
  86. LPLOGFONT lf;
  87. LPTEXTMETRIC tm;
  88. short nFontType;
  89. ENUMER FAR * enumer;
  90. {
  91.     FONT FAR * font;
  92.     
  93.     if (NULL == GlobalReAlloc (enumer->hGMem,
  94.                         (DWORD) sizeof (FONT) * (1 + enumer->nCount),
  95.                         GMEM_MOVEABLE))
  96.         return 0;
  97.     
  98.     font = (FONT FAR *) GlobalLock (enumer->hGMem) + enumer->nCount;
  99.     font->nFontType = nFontType;
  100.     font->lf = *lf;
  101.     font->tm = *tm;
  102.     
  103.     GlobalUnlock (enumer->hGMem);
  104.     enumer->nCount ++;
  105.     return 1;
  106.     }
  107.  
  108. void Display (hDC, xChar, yChar, font)
  109. HDC hDC;
  110. short xChar, yChar;
  111. FONT FAR * font;
  112. {
  113.     static FONT f;
  114.     
  115.     static char *szYN [] = { "No", "Yes"};
  116.     static char *szCS [] = { "ANSI", "?????", "Kanji", "OEM"};
  117.     static char *szOP [] = { "Default", "String", "Char", "Stroke"};
  118.     static char *szCP [] = { "Default", "Char", "Stroke", "?????"};
  119.     static char *szQU [] = { "Draft", "Default", "Proof", "?????"};
  120.     static char *szP1 [] = { "Default", "Fixed", "Variable", "?????"};
  121.     static char *szP2 [] = { "Fixed", "Variable"};
  122.     static char *szFA [] = { "Don't Care", "Roman", "Swiss", "Modern",
  123.                         "Script", "Decorative", "?????", "?????"};
  124.     static char *szVR [] = { "Vector", "Raster"};
  125.     static char *szGD [] = { "GDI", "Device"};
  126.     
  127.     static struct {
  128.         short x;
  129.         short y;
  130.         char *szFmt;
  131.         short *pData;
  132.         } shorts [] =
  133.             {  1,  1, "LOGFONT", NULL,
  134.                1,  2, "-------", NULL,
  135.                1,  3, "Height:      %10d", &f.lf.lfHeight,
  136.                1,  4, "Width:       %10d", &f.lf.lfWidth,
  137.                1,  5, "Escapement:  %10d", &f.lf.lfEscapement,
  138.                1,  6, "Orientation: %10d", &f.lf.lfOrientation,
  139.                1,  7, "Weight:      %10d", &f.lf.lfWeight,
  140.               28,  1, "TEXTMETRIC", NULL,
  141.               28,  2, "----------", NULL,
  142.               28,  3, "Height:       %5d", &f.tm.tmHeight,
  143.               28,  4, "Ascent:       %5d", &f.tm.tmAscent,
  144.               28,  5, "Descent:      %5d", &f.tm.tmDescent,
  145.               28,  6, "Int. Leading: %5d", &f.tm.tmInternalLeading,
  146.               28,  7, "Ext. Leading: %5d", &f.tm.tmExternalLeading,
  147.               28,  8, "Ave. Width:   %5d", &f.tm.tmAveCharWidth,
  148.               28,  9, "Max. Width    %5d", &f.tm.tmMaxCharWidth,
  149.               28, 10, "Weight:       %5d", &f.tm.tmWeight,
  150.               51, 10, "Overhang:     %10d", &f.tm.tmOverhang,
  151.               51, 11, "Digitized X:  %10d", &f.tm.tmDigitizedAspectX,
  152.               51, 12, "Digitized Y:  %10d", &f.tm.tmDigitizedAspectY
  153.               };
  154.         
  155.     static struct {
  156.         short x;
  157.         short y;
  158.         char *szFmt;
  159.         BYTE *pData;
  160.         } bytes [] =
  161.             { 51, 3, "First Char:   %10d", &f.tm.tmFirstChar,
  162.               51, 4, "Last Char:    %10d", &f.tm.tmLastChar,
  163.               51, 5, "Default Char: %10d", &f.tm.tmDefaultChar,
  164.               51, 6, "Break Char:   %10d", &f.tm.tmBreakChar,
  165.               };
  166.     
  167.     static struct {
  168.         short x;
  169.         short y;
  170.         char *szFmt;
  171.         BYTE *pData;
  172.         char **szArray;
  173.         short sAnd;
  174.         short sShift;
  175.         } strings [] = { 1, 8, "Italic:      %10s", &f.lf.lfItalic, szYN, 1, 0,
  176.                       1, 9, "Underline:   %10s", &f.lf.lfUnderline, szYN, 1, 0,
  177.                       1,10, "Strike-Out:  %10s", &f.lf.lfStrikeOut, szYN, 1, 0,
  178.                       1,11, "Char Set:    %10s", &f.lf.lfCharSet, szCS, 0xc0, 6,
  179.                       1,12, "Out  Prec:   %10s", &f.lf.lfOutPrecision, szOP, 3, 0,
  180.                       1,13, "Clip Prec:   %10s", &f.lf.lfClipPrecision, szCP, 3, 0,
  181.                       1,14, "Quality:     %10s", &f.lf.lfQuality, szQU, 3, 0,
  182.                       1,15, "Pitch:       %10s", &f.lf.lfPitchAndFamily, szP1, 3, 0,
  183.                       1,16, "Family:      %10s", &f.lf.lfPitchAndFamily, szFA, 0x70, 4,
  184.                      28,11, "Italic:       %5s", &f.tm.tmItalic, szYN, 1, 0,
  185.                      28,12, "Underline:    %5s", &f.tm.tmUnderlined, szYN, 1, 0,
  186.                      28,13, "Strike-Out    %5s", &f.tm.tmStruckOut, szYN, 1, 0,
  187.                      51, 7, "Pitch:        %10s", &f.tm.tmPitchAndFamily, szP2, 1, 0,
  188.                      51, 8, "Family:       %10s", &f.tm.tmPitchAndFamily, szFA, 0x70, 4,
  189.                      51, 9, "Char Set:     %10s", &f.tm.tmCharSet, szCS, 0xc0, 6,
  190.                      36,15, "Font Type:  %6s", (BYTE *) &f.nFontType, szVR, 1, 0,
  191.                      55,15, "%s", (BYTE *) &f.nFontType, szGD, 2, 1
  192.                      };
  193.         
  194.     char szBuffer [80];
  195.     int i;
  196.     
  197.     f = *font;
  198.     
  199.     for (i = 0; i < sizeof shorts / sizeof shorts [0]; i++)
  200.         TextOut (hDC, xChar * shorts[i].x, yChar * shorts[i].y, szBuffer,
  201.                 sprintf (szBuffer, shorts[i].szFmt, *shorts[i].pData));
  202.     
  203.     for (i = 0; i < sizeof bytes / sizeof bytes [0]; i++)
  204.         TextOut (hDC, xChar * bytes[i].x, yChar * bytes[i].y, szBuffer,
  205.                 sprintf (szBuffer, bytes[i].szFmt, *bytes[i].pData));
  206.     
  207.     for (i = 0; i < sizeof strings / sizeof strings [0]; i++)
  208.         TextOut (hDC, xChar * strings[i].x, yChar * strings[i].y, szBuffer,
  209.                 sprintf (szBuffer, strings[i].szFmt, (strings[i].szArray)
  210.                         [(*strings[i].pData & strings[i].sAnd) >>
  211.                                     strings[i].sShift]));
  212.     
  213.     TextOut (hDC, xChar, yChar * 17, szBuffer,
  214.             sprintf (szBuffer, "Face Name:   %10s", f.lf.lfFaceName));
  215.     }
  216.  
  217. HDC GetPrinterIC ()
  218. {
  219.     char szPrinter [64];
  220.     char *szDevice, *szDriver, *szOutput;
  221.     
  222.     GetProfileString ("windows", "device", "", szPrinter, 64);
  223.     
  224.     if ((szDevice = strtok (szPrinter, ",")) &&
  225.         (szDriver = strtok (NULL, ", ")) &&
  226.         (szOutput = strtok (NULL, ", ")))
  227.             return CreateIC(szDriver, szDevice, szOutput, NULL);
  228.     return NULL;
  229.     }
  230.  
  231. long FAR PASCAL WndProc (hWnd, iMessage, wParam, lParam)
  232. HWND hWnd;                  /* window handle             */
  233. unsigned iMessage;              /* type of message             */
  234. WORD wParam;                  /* additional information         */
  235. LONG lParam;                  /* additional information         */
  236. {
  237.     static BOOL bHaveInfo = FALSE;
  238.     static ENUMER enumer1, enumer2;
  239.     static FARPROC lpfnEnumAllFaces, lpfnEnumAllFonts;
  240.     static short xChar, yChar, nCurrent;
  241.     static WORD wCurrentDC = IDM_SCREEN;
  242.     HANDLE hInstance;
  243.     HDC hDC;
  244.     HFONT hFont;
  245.     HMENU hMenu;
  246.     FONT FAR *font;
  247.     LPSTR lpFaces;
  248.     PAINTSTRUCT ps;
  249.     short i;
  250.     TEXTMETRIC tm;
  251.     
  252.     switch (iMessage) {
  253.     
  254.         case WM_CREATE:
  255.             hInstance = ((LPCREATESTRUCT) lParam)->hInstance;
  256.             lpfnEnumAllFaces = MakeProcInstance (EnumAllFaces, hInstance);
  257.             lpfnEnumAllFonts = MakeProcInstance (EnumAllFonts, hInstance);
  258.             
  259.             hDC = GetDC (hWnd);
  260.             GetTextMetrics (hDC, (LPTEXTMETRIC) &tm);
  261.             xChar = tm.tmAveCharWidth;
  262.             yChar = tm.tmHeight + tm.tmExternalLeading;
  263.             ReleaseDC (hWnd, hDC);
  264.             break;
  265.         
  266.         case WM_COMMAND:
  267.             if (wParam == IDM_EXIT) {
  268.                 SendMessage (hWnd, WM_CLOSE, 0, 0L);
  269.                 break;
  270.                 }
  271.             else if (wParam == wCurrentDC)
  272.                 break;
  273.             
  274.             hMenu = GetMenu (hWnd);
  275.             CheckMenuItem (hMenu, wCurrentDC, MF_UNCHECKED);
  276.             CheckMenuItem (hMenu, wCurrentDC = wParam, MF_CHECKED);
  277.                     /* NO break - fall through */
  278.  
  279.         case WM_DEVMODECHANGE:
  280.         case WM_FONTCHANGE:
  281.             bHaveInfo = FALSE;
  282.             InvalidateRect (hWnd, NULL, TRUE);
  283.             break;
  284.         
  285.         case WM_PAINT:
  286.             if (!bHaveInfo) {
  287.                 if (enumer2.hGMem) GlobalFree (enumer2.hGMem);
  288.                 
  289.                 enumer1.hGMem = GlobalAlloc (GHND, 1L);
  290.                 enumer1.nCount = 0;
  291.                 
  292.                 enumer2.hGMem = GlobalAlloc (GHND, 1L);
  293.                 enumer2.nCount = 0;
  294.                 
  295.                 if (NULL == enumer1.hGMem || NULL == enumer2.hGMem)
  296.                     goto MEMORY_ERROR;
  297.                     
  298.                 if (wCurrentDC == IDM_SCREEN)
  299.                     hDC = CreateIC ("DISPLAY", NULL, NULL, NULL);
  300.                 else
  301.                     hDC = GetPrinterIC ();
  302.                 
  303.                 if (hDC) {
  304.                     if (0 == EnumFonts (hDC, NULL, lpfnEnumAllFaces,
  305.                                     (LPSTR) &enumer1))
  306.                         goto MEMORY_ERROR;
  307.                 
  308.                     lpFaces = GlobalLock (enumer1.hGMem);
  309.                 
  310.                     for (i = 0; i < enumer1.nCount; i++)
  311.                         if (0 == EnumFonts (hDC,
  312.                                         lpFaces + 1 * LF_FACESIZE,
  313.                                         lpfnEnumAllFonts,
  314.                                         (LPSTR) &enumer2))
  315.                             goto MEMORY_ERROR;
  316.                     GlobalUnlock (enumer1.hGMem);
  317.                     enumer2.nCount--;
  318.                 
  319.                     DeleteDC (hDC);
  320.                     bHaveInfo = TRUE;
  321.                     }
  322.             
  323.                 GlobalFree (enumer1.hGMem);
  324.                 SetScrollRange (hWnd, SB_VERT, 0, enumer2.nCount, FALSE);
  325.                 SetScrollPos (hWnd, SB_VERT, nCurrent = 0, TRUE);
  326.                 }
  327.         
  328.             hDC = BeginPaint (hWnd, &ps);
  329.         
  330.             if (bHaveInfo) {
  331.                 font = (FONT FAR *) GlobalLock (enumer2.hGMem) + nCurrent;
  332.                 Display (hDC, xChar, yChar, font);
  333.                 hFont = SelectObject (hDC, CreateFontIndirect (&font->lf));
  334.             
  335.                 TextOut (hDC, 1 * xChar, 19 * yChar,
  336.                     "AaBbCcDdEeFfGgHhIiJjKkLlMmNnOoPpQqRrSsTtUuVvWwXxYyZz",
  337.                     52);
  338.             
  339.                 GlobalUnlock (enumer2.hGMem);
  340.                 DeleteObject (SelectObject (hDC, hFont));
  341.                 }
  342.         
  343.             EndPaint (hWnd, &ps);
  344.             break;
  345.         
  346.         case WM_KEYDOWN:
  347.             switch (wParam) {
  348.             
  349.                 case VK_HOME:
  350.                     SendMessage (hWnd, WM_VSCROLL, SB_TOP, 0L);
  351.                     break;
  352.                 
  353.                 case VK_END:
  354.                     SendMessage (hWnd, WM_VSCROLL, SB_BOTTOM, 0L);
  355.                     break;
  356.  
  357.                 case VK_LEFT:
  358.                 case VK_UP:
  359.                 case VK_PRIOR:
  360.                     SendMessage (hWnd, WM_VSCROLL, SB_LINEUP, 0L);
  361.                     break;
  362.                 
  363.                 case VK_RIGHT:
  364.                 case VK_DOWN:
  365.                 case VK_NEXT:
  366.                     SendMessage (hWnd, WM_VSCROLL, SB_LINEDOWN, 0L);
  367.                     break;
  368.                 }
  369.             
  370.             break;
  371.         
  372.         case WM_VSCROLL:
  373.             switch (wParam) {
  374.             
  375.                 case SB_TOP:
  376.                     nCurrent = 0;
  377.                     break;
  378.                 
  379.                 case SB_BOTTOM:
  380.                     nCurrent = enumer2.nCount;
  381.                     break;
  382.                 
  383.                 case SB_LINEUP:
  384.                 case SB_PAGEUP:
  385.                     nCurrent--;
  386.                     break;
  387.                 
  388.                 case SB_LINEDOWN:
  389.                 case SB_PAGEDOWN:
  390.                     nCurrent++;
  391.                     break;
  392.                 
  393.                 case SB_THUMBPOSITION:
  394.                     nCurrent = LOWORD (lParam);
  395.                     break;
  396.                 
  397.                 default:
  398.                     return 0L;
  399.                 }
  400.             
  401.             nCurrent = min (max (0, nCurrent), enumer2.nCount);
  402.             SetScrollPos (hWnd, SB_VERT, nCurrent, TRUE);
  403.             InvalidateRect (hWnd, NULL, TRUE);
  404.             break;
  405.         
  406.         MEMORY_ERROR:
  407.             MessageBox (hWnd, "Cannot allocate memory, must end.",
  408.                 szAppName, MB_OK | MB_ICONHAND | MB_SYSTEMMODAL);
  409.                     /* NO break - fall through */
  410.         
  411.         case WM_CLOSE:
  412.             DestroyWindow (hWnd);
  413.             break;
  414.         
  415.         case WM_DESTROY:
  416.             PostQuitMessage (0);
  417.             break;
  418.         
  419.         default:
  420.             return DefWindowProc (hWnd, iMessage, wParam, lParam);
  421.         }
  422.     return 0L;
  423.     }
  424.